/*
 *  WsvJdbc - a JDBC driver for WSV (values separated by whatever) data files
 *  Copyright (C) 2004  Daniele Pes
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
package axs.jdbc.dataSourceConfiguration;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

import axs.jdbc.dataSpecification.SqlTypes;
import axs.jdbc.dataSpecification.supportedJavaTypes.TypesMapper;
import axs.jdbc.driver.WsvDriver;
import axs.jdbc.utils.ArrayUtilities;
import axs.jdbc.utils.CharFormat;
import axs.jdbc.utils.DateAndTimeFormat;


/**
 * This class is used to set up those properties needed to build a connection to a source 
 * data file and to describe the columns of the source data file (for the WsvJdbc driver).
 *
 * @author 		Daniele Pes 
 */
public class JdbcSourceConfiguration {
	private static final String DRIVER 	                   = "jdbc.sourceDriver";
	private static final String URL 		                   = "jdbc.sourceUrl";
	private static final String USER_NAME                  = "jdbc.sourceUsername";
	private static final String PASSWORD                   = "jdbc.sourcePassword";
	private static final String TABLE 	                   = "jdbc.sourceNameOfInputTable";
	private static final String WHERE 	                   = "where";
	private static final String EXT   	                   = "fileExtension";
	private static final String HEADERS   	                = "suppressHeaders";
	private static final String SEPARATOR                  = "separator";
	private static final String C_FORMAT  	                = "charset";
	private static final String DATE_FORMAT                = "dateFormat";   
	// note: default date format is yyyy-MM-dd HH:mm:ss.SSS | yyyy-MM-dd HH:mm:ss | yyyy-MM-dd |  HH:mm:ss.SSS |  HH:mm:ss
	private static final String DRIVER_PROPERTY_NAME 	    = "jdbc.sourceDriverPropertyName";
	private static final String URL_PROPERTY_NAME 		    = "jdbc.sourceUrlPropertyName";
	private static final String USER_NAME_PROPERTY_NAME    = "jdbc.sourceUsernamePropertyName";
	private static final String PASSWORD_PROPERTY_NAME     = "jdbc.sourcePasswordPropertyName";
	private static final String TABLE_PROPERTY_NAME 	    = "jdbc.sourceNameOfInputTablePropertyName";
	private static final String WHERE_PROPERTY_NAME 	    = "jdbc.sourceWherePropertyName";
	private static final String EXT_PROPERTY_NAME 		    = "jdbc.fileExtensionPropertyName";
	private static final String HEADERS_PROPERTY_NAME      = "jdbc.suppressHeadersPropertyName";
	private static final String SEPARATOR_PROPERTY_NAME    = "jdbc.separatorPropertyName";
	private static final String C_FORMAT_PROPERTY_NAME     = "jdbc.charsetPropertyName";
	private static final String DATE_FORMAT_PROPERTY_NAME  = "jdbc.dateFormatPropertyName";
	//	
	public static final String FIXED_LENGHT_SEPARATOR = "fixed_length";
	public static final String PROPERTY_SEPARATOR = ";";
	public static final String DATE_FORMAT_SEPARATOR = "|";
	//
	private Properties props = null;
	//
	public String driver 			  = "";
	public String url 				  = "";
	public String userName 			  = "";
	public String password 			  = "";
	public String nameOfSourceTable = "";
	public String where 				  = "";
	public String fileExtension 	  = "";
	public String suppressHeaders   = "";
	public String separator 		  = "";
	public String charFormat 		  = "";
	public String dateFormat		  = "";
	//
	public ColumnSpecification[] columns = null;
	//	
	//default names of properties (as specified by the SUN jdbc driver) are set
	private String driverPropertyName;
	private String urlPropertyName;
	private String userNamePropertyName;
	private String passwordPropertyName;
	private String nameOfSourceTablePropertyName;
	private String wherePropertyName;
	private String fileExtensionPropertyName;
	private String suppressHeadersPropertyName;
	private String separatorPropertyName;
	private String charFormatPropertyName;
	private String dateFormatPropertyName;
	//	
	private final String AXS_JDBC_DRIVER = "axs.jdbc.driver.WsvDriver";
	
	public JdbcSourceConfiguration() {
	}
	
	
	public JdbcSourceConfiguration(String fileName)
	throws SpecificationException{
		if(fileName.equals(""))
			fileName = JdbcSpecificationProperties.DEFAULT_PROPERTIES_FILE_NAME;
		try{
			Properties pr = getPropertiesFromFile(fileName); 
			setProperties(null, pr);			
		}
		catch(SpecificationException e){
			throw new SpecificationException("Unable to get import properties from specification file '" 
														+ fileName + "' \n-> (SpecificationException) " + e.getMessage(), false);
		}		
	}
	
	
	public JdbcSourceConfiguration(Properties specs) 
	throws SpecificationException {
		try {
			setProperties(null, specs);
		}
		catch (SpecificationException e) {
			throw new SpecificationException(
				"Unable to set JDBC parameters from passed properties -> " + e.getMessage(),
				false);
		}
	}
	
	
	/**
	 * A source configuration could be passed externally: it wouldn't be needed getting source 
	 * parameters from the default specification file.
	 */
	protected JdbcSourceConfiguration(JdbcSourceConfiguration conf) 
	throws SpecificationException {
		try {
			setProperties(conf, null);
		}
		catch (SpecificationException e) {
			throw new SpecificationException(
				"Unable to set JDBC parameters from passed configuration -> " + e.getMessage());
		}
	}
	
	
	/** 
	 * For a JDBC source to be correctly defined, a driver and an url are necessary.
	 * The source table is needed for data importing.
	 */
	protected boolean sourceIsFullyDefined() {
		//user name  and password can be unnecessary		
		return ((url != "") && (nameOfSourceTable != ""));
	}
	
	
	/** 
	 * @param src
	 * @param specs properties got from import specification file
	 * @throws DbException: if unable to register the set driver
	 * 
	 * If the passed source is valid then it's assumed to be the current one; otherwise it tries 
	 * to get the properties from the specification file and then registers the driver.
	 */
	protected void setProperties(JdbcSourceConfiguration src, 
										  Properties 				  specs) 
	throws SpecificationException {
		try {
			if (src != null && src.sourceIsFullyDefined()) {
				assign(this, src);
				registerAndTestDriver();
			}
			else {
				setProperties(specs);				
			}
		}
		catch (SpecificationException e) {
			throw new SpecificationException(
				"Unable to set source parameters from Import Specification File because:\n " + e.getMessage());
		}
	}
	
	
	/**
	 * This gets connection parameters from the properties specified in the file import.spec and sets source fields
	 */
	protected void setProperties(Properties specs) 
	throws SpecificationException {
		if (specs == null)
			throw new SpecificationException("Import Properties have not been correctly got from file: import properties are unavailable");
		else {
			int homManyColumns;
			//
			setNamesOfProperties(specs);
			// set properties			 			
			driver   			= specs.getProperty(driverPropertyName);
			registerAndTestDriver();
			url 					= setNeededProperty(specs, urlPropertyName);
			userName 			= specs.getProperty(userNamePropertyName);
			password 			= specs.getProperty(passwordPropertyName);
			nameOfSourceTable = setNeededProperty(specs, nameOfSourceTablePropertyName);
			where 				= specs.getProperty(wherePropertyName);			
			fileExtension 		= setProperty(specs, fileExtensionPropertyName, ".csv");
			suppressHeaders 	= setProperty(specs, suppressHeadersPropertyName, "false");
			separator 			= setProperty(specs, separatorPropertyName, ";");
			charFormat			= setProperty(specs, charFormatPropertyName, CharFormat.ISO_FORMAT);
			dateFormat			= setProperty(specs, dateFormatPropertyName, DateAndTimeFormat.ISO_FORMAT);
			//
			if(driver.equals(AXS_JDBC_DRIVER)){
				homManyColumns = setColumns(specs);
				if (homManyColumns <= 0)					
					System.out.println("Data source specification not complete: not any valid column specifications were provided (VARCHAR will be assumed as type).");
			}
		}
	}
	
	
	private String setProperty(Properties specs,
										String     propertyName,
										String     defaultValue) {
		String s = specs.getProperty(propertyName);
		s = (s == null || s.equals("")) ? defaultValue : s;
		return s;
	}


	private String setNeededProperty(Properties specs, 
									   		String 	  propertyName) 
	throws SpecificationException {
		String result;
		//		
		result = specs.getProperty(propertyName);
		if (result == null || result.equals("Invalid JDBC driver specification -> property " + propertyName + " wasn't specified"))
			throw new SpecificationException();
		return result;
	}
	
	
	private void setNamesOfProperties(Properties specs) 
	throws SpecificationException {		
		//
		driverPropertyName 		      = getNameOfProperty(specs, DRIVER_PROPERTY_NAME, DRIVER);
		urlPropertyName	 				= getNameOfProperty(specs, URL_PROPERTY_NAME, URL);		
		userNamePropertyName 			= getNameOfProperty(specs, USER_NAME_PROPERTY_NAME, USER_NAME);
		passwordPropertyName 			= getNameOfProperty(specs, PASSWORD_PROPERTY_NAME, PASSWORD);
		nameOfSourceTablePropertyName = getNameOfProperty(specs, TABLE_PROPERTY_NAME, TABLE);
		wherePropertyName 				= getNameOfProperty(specs, WHERE_PROPERTY_NAME, WHERE);
		fileExtensionPropertyName 		= getNameOfProperty(specs, EXT_PROPERTY_NAME, EXT);
		suppressHeadersPropertyName 	= getNameOfProperty(specs, HEADERS_PROPERTY_NAME, HEADERS);
		separatorPropertyName 			= getNameOfProperty(specs, SEPARATOR_PROPERTY_NAME, SEPARATOR);
		charFormatPropertyName 			= getNameOfProperty(specs, C_FORMAT_PROPERTY_NAME, C_FORMAT);
		dateFormatPropertyName 			= getNameOfProperty(specs, DATE_FORMAT_PROPERTY_NAME, DATE_FORMAT);
	}


	private String getNameOfProperty(Properties specs,
												String     propertyName,
												String	  defaultProprtyName) {
		String property;
		property = specs.getProperty(propertyName);
		String propName = property != null && !property.equals("") ? property : defaultProprtyName;
		return propName;
	}
	
	
	protected static void assign(JdbcSourceConfiguration srcDest, 
										  JdbcSourceConfiguration srcSource) {
		srcDest.driver 			  = srcSource.driver;
		srcDest.nameOfSourceTable = srcSource.nameOfSourceTable;
		srcDest.password 			  = srcSource.password;
		srcDest.url 				  = srcSource.url;
		srcDest.userName 			  = srcSource.userName;
		srcDest.where 				  = srcSource.where;
		srcDest.fileExtension 	  = srcSource.fileExtension;
		srcDest.suppressHeaders   = srcSource.suppressHeaders;
		srcDest.separator 		  = srcSource.separator;
		srcDest.charFormat 		  = srcSource.charFormat;
		srcDest.columns 			  = srcSource.columns;
		srcDest.dateFormat		  = srcSource.dateFormat;
	}
	
	
	/**
	 * Note: it's assumed that colums are specified using the format ColN=typeIdentifier where N is a natural number
	 * (positive integer) and also that consecutive numbers are used. Any different specification will be considered not valid.
	 *  
	 * @param specs
	 * @throws SpecificationException
	 */
	private int setColumns(Properties specs) 
	throws SpecificationException {
		int howManycols, intType;
		int width;
		Class colType;
		String colName, colTypeIdentifier, strWidth;
		// note: a column can be identified by its column name or by a positional range
		howManycols = howManyColumns(specs); 
		if (howManycols > 0) {
			columns = new ColumnSpecification[howManycols];
			// loops through column specifications
			for (int i = 0; i < howManycols; i++) { // setting columns names and SQL types
				colName 				= specs.getProperty("Col" + (i + 1) + ".name");
				if(colName == null || colName.equals(""))
					colName = "COLUMN" + i; // first position has index 0
				colTypeIdentifier = specs.getProperty("Col" + (i + 1) + ".type");
				//	verify type specification validity (column name and column type must be both specified)
				if(colTypeIdentifier == null) // at this point, somehow (name or col boundaries) a column has been identified
					colTypeIdentifier = "VARCHAR"; // default
				// get valid type, if correctly specified (it can be specified by an ordinal or by a name)						
				colType = SqlTypes.getAvalidSqlType(colTypeIdentifier);
				// a width must be specified for VARCHAR colums; default is 255
				width = 255; // default
				if (colType.equals(String.class)) {
					strWidth = specs.getProperty("Col" + (i + 1) + ".width");
					if (strWidth != null)
						width = Integer.parseInt(strWidth);
				}
				System.out.println(colName);
				intType 	  = SqlTypes.getJavaSqlTypesToSqlInt(colType);				
				columns[i] = new ColumnSpecification();				
				columns[i].setColumnName(colName); // name
				columns[i].setColumnType(intType); // type
				if (colType.equals(String.class))
					columns[i].setStrColWidth(width); // width
				if (separator.trim().equals(FIXED_LENGHT_SEPARATOR)) {
					setFixedLenghtBoundaries(specs, colName, i); // fixed lenght
               setVarcharsToBeTrimmed(specs, colName, i);
				}				
			}
		}
		return howManycols;
	}
		
   private void setVarcharsToBeTrimmed(Properties specs, String colName, int i) {
      boolean toTrim = hasToBeTrimmed(specs.getProperty("Col" + (i + 1) + ".trim"));
      columns[i].setTrim(toTrim); 
   }


   private void setFixedLenghtBoundaries(Properties specs, 
												     String 	 colName, 
												     int 		 i) 
	throws SpecificationException {				
		String  strBegin = specs.getProperty("Col" + (i + 1) + ".begin");
		String  strEnd   = specs.getProperty("Col" + (i + 1) + ".end");       
		// both must be specified
		if (strBegin.equals("") || strEnd.equals(""))
			throw new SpecificationException("The source range (begin: " + strBegin	+ " end: " + strEnd + ") specified for field "
														+ colName + " is not valid because both begin and end must be specified!");
		int begin 	= Integer.parseInt(strBegin);
		int end     = Integer.parseInt(strEnd);
		if (end < begin)
			throw new SpecificationException("The source range (begin: " + strBegin + " end: " + strEnd + ") specified for field "
														+ colName + " is not valid because it must be begin<=end");
		if ((end - begin) >= 0) {
			if (columns[i].getColumnType() == String.class && (end - begin + 1) > columns[i].getStrColWidth()) {
				throw new SpecificationException("Invalid VARCHAR column (" + colName + ") specification: the range width (" + (end - begin + 1)
															+ ") is greater than the specified width (" + columns[i].getStrColWidth() + ")!");
			}
			else {
				columns[i].setEndingPos(end);
				columns[i].setEndPos(begin);
			}
		}
		else {
			throw new SpecificationException("Invalid column (" + colName + ") specification: upper bound (" + end 
														+ ") is greater than lower bound (" + begin + ")!");
		}      
	}
			
   private boolean hasToBeTrimmed(String trim) {
      if(trim == null)
         return false;
      else
         return Boolean.valueOf(trim).booleanValue();
   }

   /**
	 * It scans the source properties searching for columns specifications. It is assumed that columns are specified
	 * using the format ColN = ... where N is a natural (positive integer) number. Note: it is assumed that columns
	 * are specified using an uninterrupted sequence of naturals. If there is a hole in the sequence (e.g.: ColN=... ColN+2 = ...)
	 * then the last column to be considered will be ColN. No checking is done about missing columns and their subsequent ones.
	 * 
	 * @param  specs 
	 * @return
	 * @throws SpecificationException
	 */
	private int howManyColumns(Properties specs) 
	throws SpecificationException {
		String col;
		int    idx;
		//
		idx = 0;
		col = "";
		do {
			col = specs.getProperty("Col" + (idx + 1) + ".name");
			if((col == null || col.equals("")) 
				&& separator.trim().equals(FIXED_LENGHT_SEPARATOR)){
				// note: a column can be identified by its column name or by a positional range
				col = specs.getProperty("Col" + (idx + 1) + ".begin");
				if(col != null && !col.equals(""))
					col = specs.getProperty("Col" + (idx + 1) + ".end");
			}
			idx++;
		}
		while (col != null && !col.equals(""));
		return --idx;
	}
	
	
	private String getStringOfNames() {
		String result, token;
		//
		result = "";
		for (int i = 0; i < columns.length; i++) {
			token   = i == columns.length - 1 ? "" : PROPERTY_SEPARATOR;
			result += columns[i].getColumnName() + token;
		}
		return result;
	}
	
	
	private String getStringOfTypes() {
		String result, token;
		//
		result = "";
		for (int i = 0; i < columns.length; i++) {
			token   = i == columns.length - 1 ? "" : PROPERTY_SEPARATOR;
			result += columns[i].getColumnSQLtype() + token;
		}
		return result;
	}
	
	
	/**
	 * @return a string like "2; null; null; null; 5"
	 */
	private String getStringOfWidths() {
		String result, token;		
		Class  colType;
		//
		result = "";
		for (int i = 0; i < columns.length; i++) {
			colType = columns[i].getColumnType(); //getColumnSQLtype();
			token   = i == columns.length - 1 ? "" : PROPERTY_SEPARATOR;			
			if (colType == String.class)
				result += columns[i].getStrColWidth() + token;
			else
				result += "null" + token;
		}
		return result;
	}
	
	
	/**
	 * @return an empty String if the separator is other than FIXED_LENGHT_SEPARATOR. Otherwise
	 * 		  it returns a string like "1-3; null; null; null; 23-45"
	 */
	private String getStringOfBoundaries() {
		String result, token;
		//
		result = "";
		if (separator.trim().equals(FIXED_LENGHT_SEPARATOR)) {
			for (int i = 0; i < columns.length; i++) {
				token   = i == columns.length - 1 ? "" : PROPERTY_SEPARATOR;
				result += columns[i].getBeginPos() + "-" + columns[i].getEndingPos() + token;
			}
		}
		return result;
	}
	
   private String getStringOfFixedVarcharsToBeTrimmed(){
      String result, token;
      //
      result = "";
      if (separator.trim().equals(FIXED_LENGHT_SEPARATOR)) {
         for (int i = 0; i < columns.length; i++) {
            token   = i == columns.length - 1 ? "" : PROPERTY_SEPARATOR;
            result += columns[i].isTrim() + token;
         }
      }
      return result;
   }
	
	/**
	 * @throws DbException
	 *  this tries to register the set driver 
	 *  (the registration can fail because, e.g., because the path of driver file is not correctly set in ths CLASSPATH)  
	 */
	private void registerAndTestDriver() 
	throws SpecificationException {
		if (driver != null && driver != "") {
			//try to register the set driver
			System.setProperty("jdbc.drivers", driver);
			System.out.println("Driver property" + driver + " was set!");
		}
		else
			throw new SpecificationException("The driver >" + driver + "< hasn't been correctly defined");
	}
	
	
	public Properties getConnectionProperties() 
	throws SpecificationException {
		props = new Properties();
		//
		setProperty(driverPropertyName, driver);
		setProperty(fileExtensionPropertyName, fileExtension);
		setProperty(userNamePropertyName, userName);
		setProperty(passwordPropertyName, password);
		setProperty(urlPropertyName, url);
		setProperty(nameOfSourceTablePropertyName, nameOfSourceTable);
		setProperty(wherePropertyName, where);
		setProperty(suppressHeadersPropertyName, suppressHeaders);
		setProperty(charFormatPropertyName, charFormat);
		setProperty(separatorPropertyName, separator);
		setProperty(dateFormatPropertyName, dateFormat);
		if(driver.equals(AXS_JDBC_DRIVER)){
			if(columns == null)
				throw new SpecificationException("columns were not properly defined (not any column was defined)!");
			setProperty(WsvDriver.COLUMN_NAMES_PROP_NAME, getStringOfNames());
			setProperty(WsvDriver.COLUMN_TYPES_PROP_NAME, getStringOfTypes());
			setProperty(WsvDriver.COLUMN_WIDTHS_PROP_NAME, getStringOfWidths());
			setProperty(WsvDriver.COLUMN_BOUNDARIES_PROP_NAME, getStringOfBoundaries());
         setProperty(WsvDriver.COLUMN_FIXED_LENGTH_TO_TRIM_PROP_NAME, getStringOfFixedVarcharsToBeTrimmed());
		}
		return props;
	}
	
	
	protected void setProperty(String propertyName, 
										String attribute) {
		if (props == null)
			props = new Properties();
		//
		if (attribute != null && !attribute.equals(""))
			props.put(propertyName, attribute);		
	}
	
	
	public String toString() {
		return 
			  "[driver ("       	  + getDriverPropertyName()            + ") = " + getDriver() 				+ "]\n"
			+ "[url ("          	  + getUrlPropertyName()               + ") = " + getUrl() 					+ "]\n"
			+ "[user name ("    	  + getUserNamePropertyName()	         + ") = "	+ getUserName()	 		+ "]\n"
			+ "[password ("     	  + getPasswordPropertyName()	         + ") = "	+ getStarsForPassword()	+ "]\n"
			+ "[source table ("    + getNameOfSourceTablePropertyName() + ") = "	+ getNameOfSourceTable()+ "]\n"
			+ "[where (" 		     + getWherePropertyName()			      + ") = "	+ getWhere()	         + "]\n"
			+ "[extension ("	  	  + getFileExtensionPropertyName()     + ") = "	+ getFileExtension()	  	+ "]\n"
			+ "[suppressHeaders (" + getSuppressHeadersPropertyName()   + ") = "	+ getSuppressHeaders()	+ "]\n"
			+ "[separator ("	     + getSeparatorPropertyName()	      + ") = "	+ getSeparator()	      + "]\n"
			+ "[char format ("	  + getCharFormatPropertyName()	      + ") = "	+ getCharFormat()	     	+ "]\n"
			+ "[date format ("	  + getDateFormatPropertyName()	      + ") = "	+ getDateFormat()	     	+ "]\n"
			+ "\nColumns specifications:\n"	+ ArrayUtilities.printArray(columns);
	}
	
	
	private String getStarsForPassword() {
		String result;
		//
		result = "";
		if (password != null) {
			for (int i = 0; i < password.length(); i++) {
				result += "*";
			}
		}
		return result;
	}
	
	
	public String getDriver() {
		return driver;
	}


	protected Properties getPropertiesFromFile(String fileName) 
	throws SpecificationException {
		Properties result;
		//
		result = null;		      
		try{
			FileInputStream in;
			// during initialization source settings are got from import specification file				
			result = new Properties();
			in    = new FileInputStream(fileName);
			result.load(in);
			in.close();
		}
		catch(IOException e){			
			throw new SpecificationException("Unable to open a stream over the file (" + fileName + ") of source specifications \n-> (IOException) " + e.getMessage());
		}
		return result;					 
	}


	protected String getHeaderInfo() throws SpecificationException {
		try {
			return ((Boolean) (TypesMapper.getTypeClass(Boolean.class)).fromString(suppressHeaders)).toString();
		}
		catch (TypeException e) {
			throw new SpecificationException("Unable to set jdbc source property 'suppressHeaders' \n-> " + e.getMessage());
		}
	}
	
	// getters and setters
	
   /**
    * @return Returns the charFormat.
    */
   private String getCharFormat() {
      return charFormat;
   }
   
   /**
    * @param charFormat The charFormat to set.
    */
   private void setCharFormat(String charFormat) {
      this.charFormat = charFormat;
   }
   
   /**
    * @return Returns the charFormatPropertyName.
    */
   private String getCharFormatPropertyName() {
      return charFormatPropertyName;
   }
   
   /**
    * @param charFormatPropertyName The charFormatPropertyName to set.
    */
   private void setCharFormatPropertyName(String charFormatPropertyName) {
      this.charFormatPropertyName = charFormatPropertyName;
   }
   
   /**
    * @return Returns the columns.
    */
   private ColumnSpecification[] getColumns() {
      return columns;
   }
   
   /**
    * @param columns The columns to set.
    */
   private void setColumns(ColumnSpecification[] columns) {
      this.columns = columns;
   }
   
   /**
    * @return Returns the dateFormat.
    */
   private String getDateFormat() {
      return dateFormat;
   }
   
   /**
    * @param dateFormat The dateFormat to set.
    */
   private void setDateFormat(String dateFormat) {
      this.dateFormat = dateFormat;
   }
   
   /**
    * @return Returns the dateFormatPropertyName.
    */
   private String getDateFormatPropertyName() {
      return dateFormatPropertyName;
   }
   
   /**
    * @param dateFormatPropertyName The dateFormatPropertyName to set.
    */
   private void setDateFormatPropertyName(String dateFormatPropertyName) {
      this.dateFormatPropertyName = dateFormatPropertyName;
   }
   
   /**
    * @return Returns the driverPropertyName.
    */
   private String getDriverPropertyName() {
      return driverPropertyName;
   }
   
   /**
    * @param driverPropertyName The driverPropertyName to set.
    */
   private void setDriverPropertyName(String driverPropertyName) {
      this.driverPropertyName = driverPropertyName;
   }
   
   /**
    * @return Returns the fileExtension.
    */
   private String getFileExtension() {
      return fileExtension;
   }
   
   /**
    * @param fileExtension The fileExtension to set.
    */
   private void setFileExtension(String fileExtension) {
      this.fileExtension = fileExtension;
   }
   
   /**
    * @return Returns the fileExtensionPropertyName.
    */
   private String getFileExtensionPropertyName() {
      return fileExtensionPropertyName;
   }
   
   /**
    * @param fileExtensionPropertyName The fileExtensionPropertyName to set.
    */
   private void setFileExtensionPropertyName(String fileExtensionPropertyName) {
      this.fileExtensionPropertyName = fileExtensionPropertyName;
   }
   
   /**
    * @return Returns the nameOfSourceTable.
    */
   private String getNameOfSourceTable() {
      return nameOfSourceTable;
   }
   
   /**
    * @param nameOfSourceTable The nameOfSourceTable to set.
    */
   private void setNameOfSourceTable(String nameOfSourceTable) {
      this.nameOfSourceTable = nameOfSourceTable;
   }
   
   /**
    * @return Returns the nameOfSourceTablePropertyName.
    */
   private String getNameOfSourceTablePropertyName() {
      return nameOfSourceTablePropertyName;
   }
   
   /**
    * @param nameOfSourceTablePropertyName The nameOfSourceTablePropertyName to set.
    */
   private void setNameOfSourceTablePropertyName(
         String nameOfSourceTablePropertyName) {
      this.nameOfSourceTablePropertyName = nameOfSourceTablePropertyName;
   }
   
   /**
    * @return Returns the password.
    */
   private String getPassword() {
      return password;
   }
   
   /**
    * @param password The password to set.
    */
   private void setPassword(String password) {
      this.password = password;
   }
   
   /**
    * @return Returns the passwordPropertyName.
    */
   private String getPasswordPropertyName() {
      return passwordPropertyName;
   }
   
   /**
    * @param passwordPropertyName The passwordPropertyName to set.
    */
   private void setPasswordPropertyName(String passwordPropertyName) {
      this.passwordPropertyName = passwordPropertyName;
   }
   
   /**
    * @return Returns the props.
    */
   private Properties getProps() {
      return props;
   }
   
   /**
    * @param props The props to set.
    */
   private void setProps(Properties props) {
      this.props = props;
   }
   
   /**
    * @return Returns the separator.
    */
   private String getSeparator() {
      return separator;
   }
   
   /**
    * @param separator The separator to set.
    */
   private void setSeparator(String separator) {
      this.separator = separator;
   }
   
   /**
    * @return Returns the separatorPropertyName.
    */
   private String getSeparatorPropertyName() {
      return separatorPropertyName;
   }
   
   /**
    * @param separatorPropertyName The separatorPropertyName to set.
    */
   private void setSeparatorPropertyName(String separatorPropertyName) {
      this.separatorPropertyName = separatorPropertyName;
   }
   
   /**
    * @return Returns the suppressHeaders.
    */
   private String getSuppressHeaders() {
      return suppressHeaders;
   }
   
   /**
    * @param suppressHeaders The suppressHeaders to set.
    */
   private void setSuppressHeaders(String suppressHeaders) {
      this.suppressHeaders = suppressHeaders;
   }
   
   /**
    * @return Returns the suppressHeadersPropertyName.
    */
   private String getSuppressHeadersPropertyName() {
      return suppressHeadersPropertyName;
   }
   
   /**
    * @param suppressHeadersPropertyName The suppressHeadersPropertyName to set.
    */
   private void setSuppressHeadersPropertyName(
         String suppressHeadersPropertyName) {
      this.suppressHeadersPropertyName = suppressHeadersPropertyName;
   }
   
   /**
    * @return Returns the url.
    */
   private String getUrl() {
      return url;
   }
   
   /**
    * @param url The url to set.
    */
   private void setUrl(String url) {
      this.url = url;
   }
   
   /**
    * @return Returns the urlPropertyName.
    */
   private String getUrlPropertyName() {
      return urlPropertyName;
   }
   
   /**
    * @param urlPropertyName The urlPropertyName to set.
    */
   private void setUrlPropertyName(String urlPropertyName) {
      this.urlPropertyName = urlPropertyName;
   }
   
   /**
    * @return Returns the userName.
    */
   private String getUserName() {
      return userName;
   }

   private void setUserName(String userName) {
      this.userName = userName;
   }
   
   /**
    * @return Returns the userNamePropertyName.
    */
   private String getUserNamePropertyName() {
      return userNamePropertyName;
   }
   
   /**
    * @param userNamePropertyName The userNamePropertyName to set.
    */
   private void setUserNamePropertyName(String userNamePropertyName) {
      this.userNamePropertyName = userNamePropertyName;
   }
   
   /**
    * @return Returns the where.
    */
   private String getWhere() {
      return where;
   }
   
   /**
    * @param where The where to set.
    */
   private void setWhere(String where) {
      this.where = where;
   }
   
   /**
    * @return Returns the wherePropertyName.
    */
   private String getWherePropertyName() {
      return wherePropertyName;
   }
   
   /**
    * @param wherePropertyName The wherePropertyName to set.
    */
   private void setWherePropertyName(String wherePropertyName) {
      this.wherePropertyName = wherePropertyName;
   }
   
   /**
    * @param driver The driver to set.
    */
   private void setDriver(String driver) {
      this.driver = driver;
   }
}
